package com.iflytek.iot.redis.sharding.core.entity;

import com.iflytek.iot.redis.sharding.core.constants.RedisShardingConstants;
import com.iflytek.iot.redis.sharding.core.utils.RedisSlotUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * 每个redis客户端对应slot信息
 *
 * @author ZuRun
 * @date 2020/2/27 17:21:28
 */
public class RedisClientInfo<T> {
    private T resource;
    private String slotName;
    private Integer virtualNodeNum;
    private SlotConfig slotConfig;

    /**
     * 对应节点与虚拟节点
     */
    private Map<String, Integer> slots = new HashMap<>(8, 1);

    public static <T> RedisClientInfo<T> instance(T resource, SlotConfig slotConfig) {
        final String slotName = getSlotName(slotConfig);
        slotConfig.setSlotName(slotName);
        slotConfig.setResources(resource);
        RedisClientInfo<T> redisClientInfo = new RedisClientInfo<>();
        redisClientInfo.resource = resource;
        redisClientInfo.slotName = slotName;
        redisClientInfo.virtualNodeNum = calcVirtualNodeNum(slotConfig.getWeight());
        redisClientInfo.slotConfig = slotConfig;
        return redisClientInfo;
    }

    private static int calcVirtualNodeNum(short weight) {
        if (weight == 0) {
            return RedisShardingConstants.DEFAULT_VIRTUAL_NODES;
        } else if (weight > 0) {
            return RedisShardingConstants.DEFAULT_VIRTUAL_NODES * (weight + 1);
        }
        return RedisShardingConstants.DEFAULT_VIRTUAL_NODES / (weight * -1 + 1);
    }

    private static String getSlotName(SlotConfig slotConfig) {
        Short slotNo = slotConfig.getSlotNo();
        return RedisSlotUtils.createSlotName(slotNo);
    }

    public String getSlotName() {
        return slotName;
    }

    public Integer getVirtualNodeNum() {
        return virtualNodeNum;
    }

    public T getResource() {
        return resource;
    }

    public SlotConfig getSlotConfig() {
        return slotConfig;
    }

    public static void main(String[] args) {
        for (short i = -10; i < 10; i++) {
            System.out.println(i + " : " + calcVirtualNodeNum(i));
        }
    }
}
